// two-phase_termination.cpp


#include <csignal>
#include <cstdio>
#include <cstdlib>

#include <atomic>
#include <chrono>
#include <thread>


namespace blogs
{


using std::atomic_bool;
using std::chrono::milliseconds;
using std::memory_order_acquire;
using std::memory_order_release;


class Countup
{

  private:

    long
    __counter__;


    atomic_bool
    __shutdownrequested__;


  public:

    Countup()
        : __counter__(0), __shutdownrequested__(false)
    {}


    void
    shutdown()
    {
        __shutdownrequested__.store(true, memory_order_release);
    }


    void
    run()
    {
        while (!__shutdownrequested__.load(memory_order_acquire)) {
            ++__counter__;
            std::printf("\tWorking: count = %ld\n", __counter__);
            std::this_thread::sleep_for(milliseconds(500));
        }
        std::printf("\tEnding: count = %ld\n", __counter__);
        std::printf("\tShutdown\n");
    }

};


void
bye(int sig = SIGTERM)
{
    std::printf("\nBye Two-Phase Termination...\n\n");
    std::exit(sig);
}


} // end of namespace blogs


int
main(int argc, char * argv[])
{
    using std::chrono::milliseconds;
    using std::thread;
    using blogs::Countup;

    std::signal(SIGINT, blogs::bye);

    std::printf("main BEGIN\n");

    Countup c;
    thread t(&Countup::run, &c);

    std::this_thread::sleep_for(milliseconds(10000));

    std::printf("main shutdown requested\n");
    c.shutdown();
    std::printf("main join\n");

    t.join();
    std::printf("main END\n");

    blogs::bye();
    return 0;
}

